package org.example.converter;

import com.alibaba.excel.converters.Converter;
import com.alibaba.excel.converters.ReadConverterContext;
import com.alibaba.excel.converters.WriteConverterContext;
import com.alibaba.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.metadata.data.ReadCellData;
import com.alibaba.excel.metadata.data.WriteCellData;
import com.alibaba.fastjson.JSON;
import cn.hutool.core.util.NumberUtil;
import org.example.annotation.EnumValueConverterRuleAnnotation;
import org.example.annotation.EnumValueDeserializeClassType;
import org.example.enums.EnumValueConverterRule;
import org.example.enums.ValueEnum;

import javax.naming.OperationNotSupportedException;
import java.lang.reflect.Field;
import java.util.Objects;

/**
 * 枚举值转换器
 * @author chenfukeng
 */
public class EnumValueToStringConverter implements Converter<ValueEnum> {

    @Override
    public ValueEnum convertToJavaData(ReadConverterContext<?> context) throws Exception {
        Field field = context.getContentProperty().getField();
        ReadCellData<?> cellData = context.getReadCellData();
        EnumValueDeserializeClassType deserializeRule = field.getAnnotation(EnumValueDeserializeClassType.class);
        if (Objects.isNull(deserializeRule)) {
            throw new OperationNotSupportedException();
        }
        Class<?> clazz = deserializeRule.value();

        if (!ValueEnum.class.isAssignableFrom(clazz)) {
            throw new OperationNotSupportedException();
        }

        Integer cellDataValue = null;
        if (CellDataTypeEnum.STRING.equals(cellData.getType()) && NumberUtil.isNumber(cellData.getStringValue())) {
            cellDataValue = Integer.valueOf(cellData.getStringValue());
        }
        if (CellDataTypeEnum.NUMBER.equals(cellData.getType())) {
            cellDataValue = cellData.getNumberValue().intValue();
        }
        if (Objects.nonNull(cellDataValue)) {
            return (ValueEnum) JSON.parse(cellDataValue.toString());
        }

        return null;
    }

    @Override
    public WriteCellData<?> convertToExcelData(WriteConverterContext<ValueEnum> context) throws Exception {
        Field field = context.getContentProperty().getField();
        ValueEnum value = context.getValue();
        EnumValueConverterRuleAnnotation valueRuleAnnotation = field.getAnnotation(EnumValueConverterRuleAnnotation.class);

        EnumValueConverterRule valueRule = Objects.nonNull(valueRuleAnnotation) ? valueRuleAnnotation.value() : EnumValueConverterRule.BY_TEXT;

        if (EnumValueConverterRule.BY_TEXT.equals(valueRule)) {
            return new WriteCellData<>(value.getText());
        } else if (EnumValueConverterRule.BY_CODE.equals(valueRule)) {
            return new WriteCellData<>(value.getCode());
        }

        return new WriteCellData<>("");
    }
}